use crate::components::component::{App, ScrollTrait};
use crate::components::enums::{AppMode, ConnectionStatus, ProtocolType};
use ratatui::crossterm::event::{
    self, Event, KeyCode, KeyEventKind, MouseEvent, MouseEventKind,
};
use std::io;
use std::time::Duration;

/// 主事件分发函数，确保一个事件只被一种模式处理
pub fn handle_event(app: &mut App, duration: u64) -> io::Result<bool> {
    if !event::poll(Duration::from_millis(duration))? {
        return Ok(app.quit_tag);
    }
    // 只关注3种事件
    match event::read()? {
        // 键盘事件
        Event::Key(key) if key.kind == KeyEventKind::Press => {
            // 我们将接收到的整个key事件的详细信息打印到日志区
            //app.logs = format!("Key Received: {:?}", key);
            if app.mode.is_prompt() {
                // 如果是弹窗
                keyboard_event_of_prompt(key.code, app);
            } else if app.mode.is_editing() {
                // 如果是编辑
                keyboard_event_of_editing_mode(key.code, app);
            } else {
                // 默认是 Normal 模式
                keyboard_event_of_normal_mode(key.code, app);
            }
        }
        // 鼠标事件
        Event::Mouse(evt) => {
            mouse_event(evt, app);
        }
        // 粘贴事件
        Event::Paste(data) => {
            app.paste(&data);
        }
        _ => {} // 忽略所有其他事件
    }

    Ok(app.quit_tag)
}

/// 弹窗下的键盘事件
fn keyboard_event_of_prompt(key_code: KeyCode, app: &mut App) {
    let current_mode = app.mode;
    match current_mode {
        // TCP/UDP/HTTP/Clear 等待 Enter/Esc 确认的弹窗
        AppMode::ConfirmingConnect
        | AppMode::ConfirmingSend
        | AppMode::ConfirmingDisconnect
        | AppMode::ConfirmingHttpRequesting
        | AppMode::ConfirmingClearScreen => {
            match key_code {
                KeyCode::Enter => {
                    match current_mode {
                        AppMode::ConfirmingConnect => app.connect(),
                        AppMode::ConfirmingSend => app.send_tcp_udp_data(),
                        AppMode::ConfirmingHttpRequesting => app.send_http_request(),
                        AppMode::ConfirmingClearScreen => app.clear(),
                        AppMode::ConfirmingDisconnect => app.disconnect(),
                        _ => unreachable!(),
                    }
                    app.reset_mode();
                }
                KeyCode::Esc => {
                    app.reset_mode();
                }
                // 严格忽略包括 Space 在内的所有其他按键
                _ => {}
            }
        }

        // 等待 Y/N 确认的弹窗
        AppMode::ConfirmingQuit => {
            if matches!(key_code, KeyCode::Char('y') | KeyCode::Char('Y')) {
                app.set_quit();
            } else {
                app.reset_mode();
            }
        }
        AppMode::ConfirmingSwitchProtocol => {
            if matches!(key_code, KeyCode::Char('y') | KeyCode::Char('Y')) {
                app.switch_protocol();
            }
            app.reset_mode();
        }
        _ => {
            // 对于其他未明确定义的弹窗，默认按 Esc 或任意键取消
            app.reset_mode();
        }
    }
}

/// 普通模式下的键盘事件
fn keyboard_event_of_normal_mode(key_code: KeyCode, app: &mut App) {
    match key_code {
        // 空格事件
        KeyCode::Char(' ') => {
            match app.protocol {
                ProtocolType::Http => {
                    // 普通模式 && http 协议。发送请求
                    app.update_mode(AppMode::ConfirmingHttpRequesting);
                }
                // 普通模式 && tcp/udp 协议
                ProtocolType::Tcp | ProtocolType::Udp => {
                    // 根据连接状态，执行不同的逻辑
                    match app.connection_status {
                        ConnectionStatus::Disconnected => {
                            // 如果未连接，则进入“连接确认”
                            app.update_mode(AppMode::ConfirmingConnect);
                        }
                        ConnectionStatus::Connected => {
                            // 如果已连接，则进入“发送确认”
                            app.update_mode(AppMode::ConfirmingSend);
                        }
                        // 如果正在连接中，则忽略 Space 键，防止重复操作
                        ConnectionStatus::Connecting => {}
                    }
                }
            }
        }

        // esc 事件: ui切换到退出弹窗
        KeyCode::Esc => app.update_mode(AppMode::ConfirmingQuit),
        // tab 事件：
        KeyCode::Tab => {
            // 如果是未连接状态，切换到确认切换协议的弹窗
            if app.is_not_connected() {
                app.update_mode(AppMode::ConfirmingSwitchProtocol);
            } else {
                // 如果已连接状态(tcp下才有这个状态),切换到断开连接的弹窗
                app.update_mode(AppMode::ConfirmingDisconnect);
            }
        }
        // s 事件，修改address
        KeyCode::Char('s') | KeyCode::Char('S') => {
            app.update_mode(AppMode::EditingAddress);
            app.current_input = app.server_addr.clone();
        }
        // r 事件：tcp/udp协议下，输入request data
        KeyCode::Char('r') | KeyCode::Char('R')
            if !app.is_http_protocol() =>
        {
            app.update_mode(AppMode::EditingData);
            app.current_input = app.request_data.clone();
        }
        // h 事件：http协议下，输入headers
        KeyCode::Char('h') | KeyCode::Char('H') if app.is_http_protocol() => {
            app.update_mode(AppMode::EditingHeaders);
        }
        // p 事件: http协议下，输入parameters
        KeyCode::Char('p') | KeyCode::Char('P') if app.is_http_protocol() => {
            app.update_mode(AppMode::EditingParams);
        }
        // p 事件：tcp/udp协议下，切换tcp udp
        KeyCode::Char('p') | KeyCode::Char('P')
            if !app.is_http_protocol() =>
        {
            app.cycle_protocol();
        }
        // b 事件：http协议下，输入request body
        KeyCode::Char('b') | KeyCode::Char('B') if app.is_http_protocol() => {
            app.update_mode(AppMode::EditingBody);
            app.current_input = app.request_http_body.clone();
        }
        // m 事件：http协议下，切换http method
        KeyCode::Char('m') | KeyCode::Char('M') if app.is_http_protocol() => {
            app.cycle_http_method();
        }
        // z 事件：http模式下，切换content-type
        KeyCode::Char('z') | KeyCode::Char('Z') if app.is_http_protocol() => {
            app.cycle_request_content_type();
        }
        // k 事件：无论协议，清空app内容
        KeyCode::Char('k') | KeyCode::Char('K') => {
            app.update_mode(AppMode::ConfirmingClearScreen);
        }
        // c 事件：无论协议，复制response-body内容到粘贴板(linux有问题，未实现.windows ok)
        KeyCode::Char('c') | KeyCode::Char('C') => {
            app.copy_response_body();
        }
        // j 事件：无论协议，复制response-cookies内容到粘贴板(linux有问题，未实现.windows ok)
        KeyCode::Char('j') | KeyCode::Char('J') if app.is_http_protocol() => {
            app.copy_http_response_cookies()
        }
        // n 事件：无论协议，复制response-headers内容到粘贴板(linux有问题，未实现.windows ok)
        KeyCode::Char('n') | KeyCode::Char('N') if app.is_http_protocol() => {
            app.copy_http_response_headers()
        }
        // d 事件：tcp/udp协议下 && 已连接，断开连接
        KeyCode::Char('d') | KeyCode::Char('D')
            if !app.is_http_protocol() && app.connected() =>
        {
            app.update_mode(AppMode::ConfirmingDisconnect);
        }
        _ => {}
    }
}

/// 处理编辑模式下的键盘事件
fn keyboard_event_of_editing_mode(key_code: KeyCode, app: &mut App) {
    match key_code {
        // enter 事件，各种输入状态下的保存。即: 把app.current_input的值赋值给对应的属性
        KeyCode::Enter => {
            match app.mode {
                AppMode::EditingAddress => app.server_addr = app.current_input.clone(),
                AppMode::EditingHeaders => app.submit_header(),
                AppMode::EditingParams => app.submit_param(),
                AppMode::EditingBody => app.request_http_body = app.current_input.clone(),
                AppMode::EditingData => app.request_data = app.current_input.clone(),
                _ => unreachable!(),
            }
            if !matches!(app.mode, AppMode::EditingHeaders | AppMode::EditingParams) {
                app.reset_mode();
                app.current_input.clear();
            }
        }
        KeyCode::Char(c) => app.current_input.push(c),
        KeyCode::Backspace => {
            app.current_input.pop();
        }
        KeyCode::Esc => {
            app.reset_mode();
            app.current_input.clear();
        }
        _ => {}
    }
}

/// 处理鼠标滚动事件 (保持不变)
fn mouse_event(key: MouseEvent, app: &mut App) {
    match key.kind {
        MouseEventKind::ScrollDown => {
            app.scroll_down();
        }
        MouseEventKind::ScrollUp => {
            app.scroll_up();
        }
        _ => {}
    }
}
